package provider;

import javax.jws.WebMethod;
import javax.jws.WebService;

import java.util.List;
import java.util.ArrayList;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import javax.xml.bind.*;

import MashupModel.*;

import com.cdyne.ws.weatherws.*;
import ws.airport.*;

@WebService(endpointInterface = "provider.WSProvider")
public class WSProviderImpl implements WSProvider {
	
	public CityAirportInformationAndForecastModel getAirportInfoAndForecastByCityAndZip(
			String city, String zip) {
		List<Table> airportsInfo = getUSAirportsByCity(city);
		ForecastReturn forecastReturn = getCityForecastByZIP(zip);
		return new CityAirportInformationAndForecastModel(airportsInfo, forecastReturn);
	}
	
	public CityAirportInformationAndWeatherModel getAirportInfoAndWeatherByCityAndZip(String city, String zip) {
		List<Table> airportsInfo = getUSAirportsByCity(city);
		WeatherReturn weatherReturn = getCityWeatherByZIP(zip);
		return new CityAirportInformationAndWeatherModel(airportsInfo, weatherReturn);
	}

	public CityAirportInformationAndForecastModel getAirportInfoAndForecastByZip(String zip) {
		ForecastReturn forecastReturn = getCityForecastByZIP(zip);
		String city = forecastReturn.getCity();
		List<Table> airportsInfo = getUSAirportsByCity(city);
		return new CityAirportInformationAndForecastModel(airportsInfo, forecastReturn);
	}
	
	public CityAirportInformationAndWeatherModel getAirportInfoAndWeatherByZip(String zip) {
		WeatherReturn weatherReturn = getCityWeatherByZIP(zip);
		String city = weatherReturn.getCity();
		List<Table> airportsInfo = getUSAirportsByCity(city);
		return new CityAirportInformationAndWeatherModel(airportsInfo, weatherReturn);
	}
	
	@SuppressWarnings("unchecked")
	public USAirportsInfoAndWeatherTypeModel getAllUSAirportsInfoAndWeatherType() {
		String allUSAirportInfo = getAirportInformationByCountry("United States");
		InputStream inputStream = new ByteArrayInputStream(allUSAirportInfo.getBytes());
		JAXBElement<NewDataSet> newDataSet = null;
		try {
			JAXBContext jaxbContext = JAXBContext.newInstance("MashupModel");
			Unmarshaller unMarshaller = jaxbContext.createUnmarshaller();
			newDataSet = (JAXBElement<NewDataSet>) unMarshaller.unmarshal(inputStream);
		} catch (JAXBException e) {
			System.err.println("Exception in getAirportInfoAndForecastByCityAndZip");
			e.printStackTrace();
		}
		NewDataSet usAirportDataset = newDataSet.getValue();
		List<Table> usAirportsInfo = usAirportDataset.getTable();
		
		ArrayOfWeatherDescription arrayOfWeatherDescription = getWeatherInformation();
		return new USAirportsInfoAndWeatherTypeModel(usAirportsInfo, arrayOfWeatherDescription);
	}
	
	private static ForecastReturn getCityForecastByZIP(String zip) {
		Weather service = new Weather();
        WeatherSoap port = service.getWeatherSoap();
        return port.getCityForecastByZIP(zip);
	}

	private static WeatherReturn getCityWeatherByZIP(String zip) {
		Weather service = new Weather();
        WeatherSoap port = service.getWeatherSoap();
        return port.getCityWeatherByZIP(zip);
	}

	private static ArrayOfWeatherDescription getWeatherInformation() {
		Weather service = new Weather();
        WeatherSoap port = service.getWeatherSoap();
        return port.getWeatherInformation();
	}

	private static String getAirportInformationByISOCountryCode(
			String countryAbbrviation) {
		Airport service = new Airport();
		AirportSoap port = service.getAirportSoap();
		return port.getAirportInformationByISOCountryCode(countryAbbrviation);
	}

	private static String getAirportInformationByCityOrAirportName(
			String cityOrAirportName) {
		Airport service = new Airport();
		AirportSoap port = service.getAirportSoap();
		return port.getAirportInformationByCityOrAirportName(cityOrAirportName);
	}

	private static String getAirportInformationByCountry(String country) {
		Airport service = new Airport();
		AirportSoap port = service.getAirportSoap();
		return port.getAirportInformationByCountry(country);
	}

	private static String getAirportInformationByAirportCode(String airportCode) {
		Airport service = new Airport();
		AirportSoap port = service.getAirportSoap();
		return port.getAirportInformationByAirportCode(airportCode);
	}
	
	@SuppressWarnings("unchecked")
	private static List<Table> getUSAirportsByCity(String city) {
		String allUSAirportInfo = getAirportInformationByCountry("United States");
		InputStream inputStream = new ByteArrayInputStream(allUSAirportInfo.getBytes());
		JAXBElement<NewDataSet> newDataSet = null;
		try {
			JAXBContext jaxbContext = JAXBContext.newInstance("MashupModel");
			Unmarshaller unMarshaller = jaxbContext.createUnmarshaller();
			newDataSet = (JAXBElement<NewDataSet>) unMarshaller.unmarshal(inputStream);
		} catch (JAXBException e) {
			System.err.println("Exception in getAirportInfoAndForecastByCityAndZip");
			e.printStackTrace();
		}
		NewDataSet usAirportDataset = newDataSet.getValue();
		List<Table> usAirportsInfo = usAirportDataset.getTable();
		List<Table> resultAirportsInfo = new ArrayList<Table>();
		for (Table t : usAirportsInfo) {
			if (t.getCityOrAirportName().contains(city.toUpperCase())) {
				resultAirportsInfo.add(t);
			}
		}
		return resultAirportsInfo;
	}
}
